package com.wsx.rpc.resilience4j.timer;

import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.timelimiter.TimeLimiter;
import io.github.resilience4j.timelimiter.TimeLimiterConfig;
import io.vavr.control.Try;

import java.time.Duration;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Supplier;

/**
 * @author wangshuaixin
 * @Title: com.wsx.rpc.resilience4j.timer.TimerTest
 * @Description: TODO
 * @date 2019/03/20
 */
public class TimerTest {


    public static void main(String[] args) {


        TimeLimiterConfig config = TimeLimiterConfig.custom()
                .timeoutDuration(Duration.ofMillis(2000))
                .cancelRunningFuture(true)
                .build();
        TimeLimiter timeLimiter = TimeLimiter.of(config);


        CircuitBreakerConfig breakerConfig = CircuitBreakerConfig.custom()
                .failureRateThreshold(10.0F)
                .waitDurationInOpenState(Duration.ofMinutes(1))
                .ringBufferSizeInHalfOpenState(10)
                .ringBufferSizeInClosedState(10)
                .build();
        CircuitBreaker circuitBreaker = CircuitBreaker.of("timer", breakerConfig);


        Supplier<Future<String>> supplier = () -> CompletableFuture.supplyAsync(() -> {
            try {
                ///int num = new Random().nextInt(10);
                ///if (num >= 5) {
                    Thread.sleep(2100);
                ///} else {
                    ///Thread.sleep(100);
                ///}
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "hello";
        });

        Callable<String> call = TimeLimiter.decorateFutureSupplier(timeLimiter, supplier);

        Callable<String> callable = CircuitBreaker.decorateCallable(circuitBreaker, call);





        for (int i = 0; i < 500; i++) {

            ///Try.ofCallable(call).onFailure(f -> System.out.println(f));
            String rtn = Try.of(callable::call).onFailure(f -> System.out.println(f)).recover(throwable -> null).get();
            System.out.println(rtn + "==" + i);

            if (i >= 20 && i <= 22) {
                try {
                    Thread.sleep(60000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
